home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / lfs / lfsMain.c < prev    next >
C/C++ Source or Header  |  1991-07-26  |  13KB  |  506 lines

  1. /* 
  2.  * lfsMain.c --
  3.  *
  4.  *    Routines for attaching and detaching LFS file systems.
  5.  *
  6.  * Copyright 1989 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/kernel/lfs/RCS/lfsMain.c,v 1.10 91/07/26 17:20:52 mendel Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include <sprite.h>
  21. #include <lfs.h>
  22. #include <lfsInt.h>
  23. #include <stdlib.h>
  24. #include <fsioDevice.h>
  25. #include <fsdm.h>
  26. #include <proc.h>
  27. #include <string.h>
  28. #include <fsCmd.h>
  29.  
  30.  
  31. typedef struct CheckPointData {
  32.     Lfs        *lfsPtr;    /* Lfs data structure of file system. */
  33.     Boolean    interval;    /* Set to TRUE if the checkpoint should
  34.                  * stop. */
  35. } CheckPointData;
  36.  
  37. static void CheckpointCallBack _ARGS_((ClientData clientData, 
  38.         Proc_CallInfo *callInfoPtr));
  39. static ReturnStatus GetDomainFromCmdArgs _ARGS_((int *bufSizePtr, 
  40.             char **bufferPtr, Fsdm_Domain **domainPtrPtr));
  41.  
  42.  
  43. /*
  44.  *----------------------------------------------------------------------
  45.  *
  46.  * Lfs_Init --
  47.  *
  48.  *    Initialized the modules of LFS.
  49.  *
  50.  * Results:
  51.  *    None.
  52.  *
  53.  * Side effects:
  54.  *    Memory may be allocated.
  55.  *
  56.  *----------------------------------------------------------------------
  57.  */
  58. void
  59. Lfs_Init() 
  60. {
  61.     LfsFileLayoutInit();
  62.     LfsDescMapInit();
  63.     LfsSegUsageInit();
  64.  
  65.     Fsdm_RegisterDiskManager("LFS", Lfs_AttachDisk);
  66. }
  67.  
  68. /*
  69.  *----------------------------------------------------------------------
  70.  *
  71.  * Lfs_AttachDomain --
  72.  *
  73.  *    Attach a LFS file system from the specified device. 
  74.  *
  75.  * Results:
  76.  *    SUCCESS if device is attached, FAILURE otherwise.
  77.  *
  78.  * Side effects:
  79.  *    LFS modules initialied if this is the first LFS attached.
  80.  *
  81.  *----------------------------------------------------------------------
  82.  */
  83.  
  84. ReturnStatus
  85. Lfs_AttachDisk(devicePtr, localName, flags, domainNumPtr)
  86.     Fs_Device    *devicePtr;    /* Device containing file system. */
  87.     char *localName;        /* The local prefix for the domain */
  88.     int  flags;            /* Attach flags. */
  89.     int *domainNumPtr;        /* OUT: Domain number allocated. */
  90. {
  91.     Lfs            *lfsPtr;
  92.     LfsDiskAddr        diskAddr;
  93.     ReturnStatus    status;
  94.     CheckPointData     *cpDataPtr;
  95.     /*
  96.      * Allocate space for the Lfs data structure fill in the fields need
  97.      * by the rest of the Lfs module to perform initialization correctly.
  98.      */
  99.     lfsPtr = (Lfs *) malloc(sizeof(*lfsPtr));
  100.     bzero((char *)lfsPtr, sizeof(*lfsPtr));
  101.     lfsPtr->devicePtr = devicePtr;
  102.     lfsPtr->name = localName;
  103.     lfsPtr->name = malloc(strlen(localName)+1);
  104.     lfsPtr->controlFlags = 0;
  105.     (void) strcpy(lfsPtr->name, localName);
  106.     lfsPtr->attachFlags = flags;
  107.  
  108.     /*
  109.      * Read the super block of the file system. Put a lot of trust in the
  110.      * magic number. 
  111.      */
  112.     LfsOffsetToDiskAddr(LFS_SUPER_BLOCK_OFFSET, &diskAddr);
  113.     status = LfsReadBytes(lfsPtr, diskAddr,  LFS_SUPER_BLOCK_SIZE,
  114.          (char *) &(lfsPtr->superBlock));
  115.     if (status != SUCCESS) {
  116.     free((char *) lfsPtr);
  117.     return status;
  118.     }
  119.     /*
  120.      * Validate the super block here.
  121.      */
  122.     if ((lfsPtr->superBlock.hdr.magic != LFS_SUPER_BLOCK_MAGIC) ||
  123.     (lfsPtr->superBlock.hdr.version != LFS_SUPER_BLOCK_VERSION)) {
  124.     free((char *) lfsPtr);
  125.     return FAILURE;
  126.     }
  127.     lfsPtr->blockSizeShift = LfsLogBase2((unsigned)LfsBlockSize(lfsPtr));
  128.     lfsPtr->checkpointIntervalPtr = (int *) NIL;
  129.     Sync_LockInitDynamic(&(lfsPtr->lock), "LfsLock");
  130.     lfsPtr->activeFlags = 0;
  131.     lfsPtr->cleanerProcPtr = (Proc_ControlBlock *) NIL;
  132.     lfsPtr->dirModsActive = 0;
  133.     lfsPtr->numDirtyBlocks = 0;
  134.     status = LfsLoadFileSystem(lfsPtr, flags); 
  135.     if (status != SUCCESS) { 
  136.     free((char *)lfsPtr);
  137.     return status;
  138.     }
  139.     LfsMemInit(lfsPtr);
  140.     *domainNumPtr = lfsPtr->domainPtr->domainNumber;
  141.     /*
  142.      * Make our own copy of the prefix name.
  143.      */
  144.     lfsPtr->name = malloc(strlen(localName)+1);
  145.     (void) strcpy(lfsPtr->name, localName);
  146.     cpDataPtr = (CheckPointData *) malloc(sizeof(*cpDataPtr));
  147.     cpDataPtr->lfsPtr = lfsPtr;
  148.     cpDataPtr->interval = lfsPtr->superBlock.hdr.checkpointInterval *
  149.                 timer_IntOneSecond;
  150.  
  151.     lfsPtr->checkpointIntervalPtr = &(cpDataPtr->interval);
  152.  
  153.     Proc_CallFunc(CheckpointCallBack, (ClientData) cpDataPtr,
  154.             cpDataPtr->interval);
  155.     return status;
  156. }
  157.  
  158. /*
  159.  *----------------------------------------------------------------------
  160.  *
  161.  * Lfs_DetachDomain --
  162.  *
  163.  *    Detach a LFS file system domain.
  164.  *
  165.  * Results:
  166.  *    SUCCESS if device is detached, FAILURE otherwise.
  167.  *
  168.  * Side effects:
  169.  *
  170.  *----------------------------------------------------------------------
  171.  */
  172.  
  173. ReturnStatus
  174. Lfs_DetachDisk(domainPtr)
  175.      Fsdm_Domain *domainPtr;    /* Domain to detach. */
  176.  
  177. {
  178.     Lfs    *lfsPtr = LfsFromDomainPtr(domainPtr);
  179.     ReturnStatus status;
  180.  
  181.     status = LfsDetachFileSystem(lfsPtr);
  182.     LfsMemDetach(lfsPtr);
  183.     Fscache_UnregisterBackend(lfsPtr->domainPtr->backendPtr);
  184.     lfsPtr->domainPtr->backendPtr = (Fscache_Backend *) NIL;
  185.     Sync_LockClear(&lfsPtr->lock);
  186.     free(lfsPtr->name);
  187.     free((char *)lfsPtr);
  188.     return status;
  189. }
  190.  
  191.  
  192. /*
  193.  *----------------------------------------------------------------------
  194.  *
  195.  * Lfs_RereadSummaryInfo --
  196.  *
  197.  *    Reread the summary sector associated with the prefix and update
  198.  *    the domain information. This should be called if the summary
  199.  *    sector on the disk has been changed since the domain was attached.
  200.  *    LFS uses this call to reread the superBlock and get any changes made.
  201.  *
  202.  * Results:
  203.  *    SUCCESS 
  204.  *
  205.  * Side effects:
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209. /*ARGSUSED*/
  210. ReturnStatus
  211. Lfs_RereadSummaryInfo(domainPtr)
  212.     Fsdm_Domain        *domainPtr;    /* Domain to reread summary for. */
  213. {
  214.     Lfs    *lfsPtr = LfsFromDomainPtr(domainPtr);
  215.     LfsDiskAddr        diskAddr;
  216.     ReturnStatus status;
  217.     LfsSuperBlock    newSuperBlock;
  218.     /*
  219.      * Read the super block of the file system. Put a lot of trust in the
  220.      * magic number. 
  221.      */
  222.     LfsOffsetToDiskAddr(LFS_SUPER_BLOCK_OFFSET, &diskAddr);
  223.     status = LfsReadBytes(lfsPtr, diskAddr,  LFS_SUPER_BLOCK_SIZE,
  224.          (char *) &newSuperBlock);
  225.     if (status != SUCCESS) {
  226.     return status;
  227.     }
  228.     /*
  229.      * Validate the super block here.
  230.      */
  231.     if ((newSuperBlock.hdr.magic != LFS_SUPER_BLOCK_MAGIC) ||
  232.     (newSuperBlock.hdr.version != LFS_SUPER_BLOCK_VERSION)) {
  233.     return FAILURE;
  234.     }
  235.     /*
  236.      * Looks ok, update our incore version.
  237.      */
  238.     bcopy((char *) &newSuperBlock, (char *) &lfsPtr->superBlock,
  239.         sizeof(LfsSuperBlock));
  240.     return SUCCESS;
  241. }
  242.  
  243.  
  244.  
  245. /*
  246.  *----------------------------------------------------------------------
  247.  *
  248.  * Lfs_DomainWriteBack --
  249.  *
  250.  *    Force all domain information to disk.
  251.  *
  252.  * Results:
  253.  *    Error code if the write failed.
  254.  *
  255.  * Side effects:
  256.  *    None.
  257.  *
  258.  *----------------------------------------------------------------------
  259.  */
  260. ReturnStatus
  261. Lfs_DomainWriteBack(domainPtr, shutdown)
  262.     Fsdm_Domain    *domainPtr;    /* Domain to be written back. */
  263.     Boolean    shutdown;    /* TRUE if are syncing to shutdown the system.*/
  264. {
  265.     Lfs    *lfsPtr = LfsFromDomainPtr(domainPtr);
  266.  
  267.     return LfsCheckPointFileSystem(lfsPtr, LFS_CHECKPOINT_WRITEBACK);
  268.  
  269. }
  270.  
  271. /*
  272.  *----------------------------------------------------------------------
  273.  *
  274.  * GetDomainFromCmdArgs --
  275.  *
  276.  *    Return the Fsdm_Domain specified in the Lfs_Command arguments.
  277.  *    This routine updates the bufSize and bufferPtr to remove the
  278.  *    domain specifier argument.
  279.  *
  280.  * Results:
  281.  *    SUCCESS if domain fetched.
  282.  *
  283.  * Side effects:
  284.  *    None.
  285.  *
  286.  *----------------------------------------------------------------------
  287.  */
  288.  
  289.  
  290. static ReturnStatus
  291. GetDomainFromCmdArgs(bufSizePtr, bufferPtr, domainPtrPtr)
  292.     int    *bufSizePtr;    /* Size of Lfs_Command argument buffer. */
  293.     char **bufferPtr;    /* Argument buffer. */
  294.     Fsdm_Domain    **domainPtrPtr; /* OUT: Lfs Domain specified by arguments. */
  295. {
  296.     int        bufSize = (*bufSizePtr);
  297.     char    *buffer = (*bufferPtr);
  298.     int        domainNumber;
  299.     Fsdm_Domain    *domainPtr;
  300.  
  301.     if (bufSize < sizeof(int)) {
  302.     return GEN_INVALID_ARG;
  303.     }
  304.     bcopy(buffer, (char *) &domainNumber, sizeof(int));
  305.     domainPtr = Fsdm_DomainFetch(domainNumber, FALSE);
  306.     if (domainPtr == (Fsdm_Domain *) NIL) {
  307.     return GEN_INVALID_ARG;
  308.     }
  309.     if (domainPtr->domainOpsPtr->attachDisk != Lfs_AttachDisk) {
  310.     Fsdm_DomainRelease(domainNumber);
  311.     return GEN_INVALID_ARG;
  312.     }
  313.     (*domainPtrPtr) = domainPtr;
  314.     (*bufSizePtr) -= sizeof(int);
  315.     (*bufferPtr) += sizeof(int);
  316.     return SUCCESS;
  317. }
  318.  
  319. /*
  320.  *----------------------------------------------------------------------
  321.  *
  322.  * Lfs_Command --
  323.  *
  324.  *    Perform a user specified command on a LFS file system
  325.  *
  326.  * Results:
  327.  *    SUCCESS if the operation succeeded. An ReturnStatus otherwise.
  328.  *
  329.  * Side effects:
  330.  *    None.
  331.  *
  332.  *----------------------------------------------------------------------
  333.  */
  334.  
  335.  
  336. ReturnStatus
  337. Lfs_Command(command, bufSize, buffer)
  338.     int command;    /* Command to perform. */
  339.     int bufSize;    /* Size of the user's input/output buffer. */
  340.     Address buffer;    /* The user's input or output buffer. */
  341. {
  342.     Lfs    *lfsPtr;
  343.     ReturnStatus status;
  344.     Fsdm_Domain    *domainPtr;
  345.     char    *outBufferPtr = buffer;
  346.  
  347.     switch (command) {
  348.     case    FS_CLEAN_LFS_COMMAND: {
  349.         status = GetDomainFromCmdArgs(&bufSize, &buffer, &domainPtr);
  350.         if (status != SUCCESS) {
  351.         return status;
  352.         }
  353.         lfsPtr = (Lfs *) domainPtr->clientData;
  354.         LfsSegCleanStart(lfsPtr);
  355.         Fsdm_DomainRelease(domainPtr->domainNumber);
  356.         break;
  357.     }
  358.     case FS_SET_CONTROL_FLAGS_LFS_COMMAND: {
  359.         status = GetDomainFromCmdArgs(&bufSize, &buffer, &domainPtr);
  360.         if (status != SUCCESS) {
  361.         return status;
  362.         }
  363.         lfsPtr = (Lfs *) domainPtr->clientData;
  364.         if (bufSize >= sizeof(int)) {
  365.         bcopy(buffer, (char *) &(lfsPtr->controlFlags), sizeof(int));
  366.         } else {
  367.         status = GEN_INVALID_ARG;
  368.         }
  369.         Fsdm_DomainRelease(domainPtr->domainNumber);
  370.         break;
  371.     }
  372.     case FS_GET_CONTROL_FLAGS_LFS_COMMAND: {
  373.         status = GetDomainFromCmdArgs(&bufSize, &buffer, &domainPtr);
  374.         if (status != SUCCESS) {
  375.         return status;
  376.         }
  377.         lfsPtr = (Lfs *) domainPtr->clientData;
  378.         if (bufSize >= sizeof(int)) {
  379.         bcopy((char *) &(lfsPtr->controlFlags), outBufferPtr, 
  380.                 sizeof(int));
  381.         } else {
  382.         status = GEN_INVALID_ARG;
  383.         }
  384.         Fsdm_DomainRelease(domainPtr->domainNumber);
  385.         break;
  386.     }
  387.     case FS_FREE_FILE_NUMBER_LFS_COMMAND: {
  388.         int    fileNumber;
  389.         status = GetDomainFromCmdArgs(&bufSize, &buffer, &domainPtr);
  390.         if (status != SUCCESS) {
  391.         return status;
  392.         }
  393.         lfsPtr = (Lfs *) domainPtr->clientData;
  394.         if (bufSize >= sizeof(int)) {
  395.         bcopy(buffer, (char *) &fileNumber, sizeof(int));
  396.         printf("Lfs_FreeFileNumber(%s,%d)\n", lfsPtr->name, 
  397.                 fileNumber);
  398.         status = Lfs_FreeFileNumber(domainPtr, fileNumber);
  399.         } else {
  400.         status = GEN_INVALID_ARG;
  401.         }
  402.         Fsdm_DomainRelease(domainPtr->domainNumber);
  403.         return status;
  404.     }
  405.     default: {
  406.         status = GEN_INVALID_ARG;
  407.     }
  408.     }
  409.     return status;
  410. }
  411.  
  412. /*
  413.  *----------------------------------------------------------------------
  414.  *
  415.  * CheckpointCallBack --
  416.  *
  417.  *    A Proc_CallFunc for checkpoint LFS file systems.
  418.  *
  419.  * Results:
  420.  *    None
  421.  *
  422.  * Side effects:
  423.  *    None.
  424.  *
  425.  *----------------------------------------------------------------------
  426.  */
  427. static void
  428. CheckpointCallBack(clientData, callInfoPtr)
  429.     ClientData       clientData;        /* Lfs structure of LFS */
  430.     Proc_CallInfo    *callInfoPtr;
  431. {
  432.  
  433.     CheckPointData *cpDataPtr = (CheckPointData *) clientData;
  434.     Lfs    *lfsPtr = cpDataPtr->lfsPtr;
  435.  
  436.     if (cpDataPtr->interval > 0) {
  437.     (void) LfsCheckPointFileSystem(lfsPtr, LFS_CHECKPOINT_TIMER);
  438.     callInfoPtr->interval = cpDataPtr->interval;
  439.     } else if (cpDataPtr->interval == 0) {
  440.     free((char *) cpDataPtr);
  441.     callInfoPtr->interval = 0;
  442.     } else {
  443.     callInfoPtr->interval = -cpDataPtr->interval;
  444.     }
  445. }
  446.  
  447. /*
  448.  *----------------------------------------------------------------------
  449.  *
  450.  * LfsLogBase2 --
  451.  *
  452.  *    Compute the log base 2 of the given integer. The argument is assumed
  453.  *    to have only one bit set in it.
  454.  *
  455.  * Results:
  456.  *    Log base 2 of the integer.
  457.  *
  458.  * Side effects:
  459.  *
  460.  *----------------------------------------------------------------------
  461.  */
  462.  
  463. int
  464. LfsLogBase2(val)
  465.     unsigned    int    val;    /* Value of take log of. */
  466. {
  467.     register int     bit;
  468.  
  469.     for (bit = 0; bit < sizeof(val)*8; bit++) {
  470.     if (val & (1 << bit)) {
  471.         break;
  472.     }
  473.     }
  474.     if (val != (1 << bit)) {
  475.     panic("LfsLogBase2: Botched computation of %d\n", val);
  476.     }
  477.     return bit;
  478. }
  479.  
  480. /*
  481.  *----------------------------------------------------------------------
  482.  *
  483.  * LfsError --
  484.  *
  485.  *    Print an error message.
  486.  *
  487.  * Results:
  488.  *    None.
  489.  *
  490.  * Side effects:
  491.  *    None.
  492.  *
  493.  *----------------------------------------------------------------------
  494.  */
  495.  
  496. void
  497. LfsError(lfsPtr, status, message)
  498.     Lfs    *lfsPtr;
  499.     ReturnStatus status;
  500.     char *message;
  501. {
  502.     panic("LfsError: on %s status 0x%x, %s\n", lfsPtr->name, status, message);
  503. }
  504.  
  505.  
  506.